32.1 企业网络配置

13 分钟阅读

32.1.1 代理服务器配置#

HTTP/HTTPS 代理#

Claude Code 支持标准的环境变量来配置代理服务器:

HTTPS 代理(推荐)

export HTTPS_PROXY=https://proxy.example.com:8080

HTTP 代理(如果 HTTPS 不可用)

export HTTP_PROXY=http://proxy.example.com:8080

代理白名单(不通过代理的地址)

export NO_PROXY="localhost 127.0.0.1 192.168.1.1 example.com .example.com"

代理配置管理器#

bash
python

class ProxyConfigManager:
    """代理配置管理器"""

    def __init__(self):
        self.config = {
            'https_proxy': None,
            'http_proxy': None,
            'no_proxy': [],
            'proxy_auth': None
        }

    def configure(self, proxy_settings: Dict) -> ConfigResult:
        """配置代理"""
        result = ConfigResult()

        # 设置 HTTPS 代理
        if 'https_proxy' in proxy_settings:
            self.config['https_proxy'] = proxy_settings['https_proxy']
            os.environ['HTTPS_PROXY'] = self.config['https_proxy']
            result.add_setting('HTTPS_PROXY', self.config['https_proxy'])

        # 设置 HTTP 代理
        if 'http_proxy' in proxy_settings:
            self.config['http_proxy'] = proxy_settings['http_proxy']
            os.environ['HTTP_PROXY'] = self.config['http_proxy']
            result.add_setting('HTTP_PROXY', self.config['http_proxy'])

        # 设置白名单
        if 'no_proxy' in proxy_settings:
            no_proxy_list = ' '.join(proxy_settings['no_proxy'])
            self.config['no_proxy'] = proxy_settings['no_proxy']
            os.environ['NO_PROXY'] = no_proxy_list
            result.add_setting('NO_PROXY', no_proxy_list)

        # 验证配置
        validation = self._validate_config()
        result.validation = validation

        return result

    def _validate_config(self) -> ValidationResult:
        """验证配置"""
        validation = ValidationResult()

        # 检查代理 URL 格式
        for proxy_type in ['https_proxy', 'http_proxy']:
            proxy_url = self.config.get(proxy_type)
            if proxy_url:
                if not self._is_valid_url(proxy_url):
                    validation.add_error(
                        f"Invalid {proxy_type} URL: {proxy_url}"
                    )

        # 测试代理连接
        if self.config.get('https_proxy'):
            if not self._test_proxy_connection(self.config['https_proxy']):
                validation.add_error(
                    "Cannot connect to HTTPS proxy"
                )

        return validation

    def _is_valid_url(self, url: str) -> bool:
        """验证 URL 格式"""
        try:
            result = urllib.parse.urlparse(url)
            return all([result.scheme, result.netloc])
        except Exception:
            return False

    def _test_proxy_connection(self, proxy_url: str) -> bool:
        """测试代理连接"""
        try:
            parsed = urllib.parse.urlparse(proxy_url)
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(5)
            result = sock.connect_ex((parsed.hostname, parsed.port or 8080))
            sock.close()
            return result == 0
        except Exception:
            return False

### 代理身份验证

#### 基本身份验证

# 在代理 URL 中包含凭据
export HTTPS_PROXY=http://username:password@proxy.example.com:8080
export HTTP_PROXY=http://username:password@proxy.example.com:8080

NTLM/Kerberos 认证

对于需要高级身份验证的代理,建议使用 LLM 网关:

bash
bash

# 配置 LLM 网关处理代理认证
export ANTHROPIC_BASE_URL=https://llm-gateway.company.com
export ANTHROPIC_AUTH_TOKEN=gateway-token

### 代理配置最佳实践

## 32.1.2 自定义 CA 证书

### 配置自定义 CA

企业环境通常使用自定义证书颁发机构(CA)来签发内部证书。Claude Code 需要配置以信任这些 CA:

# 配置自定义 CA 证书
export NODE_EXTRA_CA_CERTS=/path/to/ca-cert.pem
# 或使用多个证书
export NODE_EXTRA_CA_CERTS=/path/to/ca1.pem:/path/to/ca2.pem

CA 证书管理器#

bash
python

class CACertificateManager:
    """CA 证书管理器"""

    def __init__(self):
        self.certificates = []
        self.certificate_store = '/etc/ssl/certs'

    def add_certificate(self, cert_path: str) -> CertResult:
        """添加 CA 证书"""
        result = CertResult()

        # 验证证书
        if not self._validate_certificate(cert_path):
            result.success = False
            result.error = "Invalid certificate"
            return result

        # 复制证书到存储
        cert_name = os.path.basename(cert_path)
        dest_path = os.path.join(self.certificate_store, cert_name)

        shutil.copy(cert_path, dest_path)
        self.certificates.append(dest_path)

        # 更新环境变量
        self._update_ca_bundle()

        result.success = True
        result.certificate_path = dest_path

        return result

    def _validate_certificate(self, cert_path: str) -> bool:
        """验证证书"""
        try:
            with open(cert_path, 'rb') as f:
                cert_data = f.read()

            # 使用 OpenSSL 验证
            result = subprocess.run(
                ['openssl', 'x509', '-in', cert_path, '-noout'],
                capture_output=True
            )

            return result.returncode == 0
        except Exception:
            return False

    def _update_ca_bundle(self):
        """更新 CA 包"""
        cert_paths = ':'.join(self.certificates)
        os.environ['NODE_EXTRA_CA_CERTS'] = cert_paths

### 证书格式转换

# 将 DER 格式转换为 PEM 格式
openssl x509 -inform der -in certificate.cer -out certificate.pem
# 将 PKCS#12 格式转换为 PEM 格式
openssl pkcs12 -in certificate.p12 -out certificate.pem -nodes
# 提取证书链
openssl s_client -connect server:port -showcerts

32.1.3 mTLS 身份验证#

mTLS 配置#

对于需要客户端证书身份验证的企业环境:

bash
bash

# 客户端证书
export CLAUDE_CODE_CLIENT_CERT=/path/to/client-cert.pem

# 客户端私钥
export CLAUDE_CODE_CLIENT_KEY=/path/to/client-key.pem

# 私钥密码短语(如果加密)
export CLAUDE_CODE_CLIENT_KEY_PASSPHRASE="your-passphrase"

### mTLS 配置管理器

class MTLSConfigManager:
"""mTLS 配置管理器"""
def __init__(self):
self.config = {
'client_cert': None,
'client_key': None,
'key_passphrase': None
}
def configure(self, mtls_settings: Dict) -> ConfigResult:
"""配置 mTLS"""
result = ConfigResult()
# 设置客户端证书
if 'client_cert' in mtls_settings:
cert_path = mtls_settings['client_cert']
if self._validate_certificate(cert_path):
self.config['client_cert'] = cert_path
os.environ['CLAUDE_CODE_CLIENT_CERT'] = cert_path
result.add_setting('CLAUDE_CODE_CLIENT_CERT', cert_path)
else:
result.add_error("Invalid client certificate")
# 设置客户端密钥
if 'client_key' in mtls_settings:
key_path = mtls_settings['client_key']
if self._validate_key(key_path):
self.config['client_key'] = key_path
os.environ['CLAUDE_CODE_CLIENT_KEY'] = key_path
result.add_setting('CLAUDE_CODE_CLIENT_KEY', key_path)
else:
result.add_error("Invalid client key")
# 设置密钥密码短语
if 'key_passphrase' in mtls_settings:
self.config['key_passphrase'] = mtls_settings['key_passphrase']
os.environ['CLAUDE_CODE_CLIENT_KEY_PASSPHRASE'] = \
mtls_settings['key_passphrase']
result.add_setting('CLAUDE_CODE_CLIENT_KEY_PASSPHRASE', '***')
# 验证配置
validation = self._validate_mtls_config()
result.validation = validation
return result
def _validate_key(self, key_path: str) -> bool:
"""验证私钥"""
try:
result = subprocess.run(
['openssl', 'rsa', '-in', key_path, '-check', '-noout'],
capture_output=True
)
return result.returncode == 0
except Exception:
return False
def _validate_mtls_config(self) -> ValidationResult:
"""验证 mTLS 配置"""
validation = ValidationResult()
# 检查证书和密钥是否匹配
if (self.config['client_cert'] and
self.config['client_key']):
if not self._check_cert_key_match():
validation.add_error(
"Certificate and key do not match"
)
return validation
def _check_cert_key_match(self) -> bool:
"""检查证书和密钥是否匹配"""
try:
# 提取证书的公钥模数
cert_result = subprocess.run(
['openssl', 'x509', '-noout', '-modulus', '-in',
self.config['client_cert']],
capture_output=True,
text=True
)
# 提取密钥的公钥模数
key_result = subprocess.run(
['openssl', 'rsa', '-noout', '-modulus', '-in',
self.config['client_key']],
capture_output=True,
text=True
)
return cert_result.stdout == key_result.stdout
except Exception:
return False

32.1.4 网络访问要求#

必需的 URL#

Claude Code 需要访问以下 URL:

URL用途协议
api.anthropic.comClaude API 端点HTTPS
claude.aiWebFetch 保护措施HTTPS
statsig.anthropic.com遥测和指标HTTPS
sentry.io错误报告HTTPS

防火墙配置#

bash
python

class FirewallConfigurator:
    """防火墙配置器"""

    def __init__(self):
        self.required_urls = [
            'api.anthropic.com',
            'claude.ai',
            'statsig.anthropic.com',
            'sentry.io'
        ]

    def generate_rules(self,
                       firewall_type: str = 'iptables') -> List[str]:
        """生成防火墙规则"""
        rules = []

        if firewall_type == 'iptables':
            rules = self._generate_iptables_rules()
        elif firewall_type == 'aws':
            rules = self._generate_aws_rules()
        elif firewall_type == 'gcp':
            rules = self._generate_gcp_rules()

        return rules

    def _generate_iptables_rules(self) -> List[str]:
        """生成 iptables 规则"""
        rules = []

        for url in self.required_urls:
            # 解析域名获取 IP
            try:
                ips = socket.gethostbyname_ex(url)[2]
                for ip in ips:
                    rule = f"iptables -A OUTPUT -d {ip} -p tcp --dport 443 -j ACCEPT"
                    rules.append(rule)
            except socket.gaierror:
                pass

        return rules

    def _generate_aws_rules(self) -> List[str]:
        """生成 AWS 安全组规则"""
        rules = []

        for url in self.required_urls:
            # AWS 需要使用 IP 范围
            # 这里简化处理,实际需要查询 IP 范围
            rule = {
                'type': 'egress',
                'protocol': 'tcp',
                'port': 443,
                'destination': url,
                'action': 'allow'
            }
            rules.append(rule)

        return rules

    def _generate_gcp_rules(self) -> List[str]:
        """生成 GCP 防火墙规则"""
        rules = []

        for url in self.required_urls:
            rule = {
                'direction': 'EGRESS',
                'action': 'ALLOW',
                'rules': [{
                    'protocol': 'tcp',
                    'ports': ['443'],
                    'destinationRanges': [self._resolve_ip_range(url)]
                }]
            }
            rules.append(rule)

        return rules

    def _resolve_ip_range(self, url: str) -> str:
        """解析 IP 范围"""
        # 简化实现,实际需要查询 DNS 或 IP 范围
        try:
            ip = socket.gethostbyname(url)
            return f"{ip}/32"
        except socket.gaierror:
            return "0.0.0.0/0"

### 网络连接测试

class NetworkTester:
"""网络测试器"""
def __init__(self):
self.required_urls = [
'https://api.anthropic.com',
'https://claude.ai',
'https://statsig.anthropic.com'
]
def test_all(self) -> NetworkTestResult:
"""测试所有网络连接"""
result = NetworkTestResult()
for url in self.required_urls:
test_result = self._test_url(url)
result.add_result(url, test_result)
# 生成报告
result.summary = self._generate_summary(result.results)
return result
def _test_url(self, url: str) -> URLTestResult:
"""测试单个 URL"""
result = URLTestResult(url=url)
try:
start_time = time.time()
response = requests.get(url, timeout=10)
end_time = time.time()
result.success = response.status_code == 200
result.latency = (end_time - start_time) * 1000  # ms
result.status_code = response.status_code
except requests.exceptions.Timeout:
result.success = False
result.error = "Timeout"
except requests.exceptions.ConnectionError:
result.success = False
result.error = "Connection error"
except Exception as e:
result.success = False
result.error = str(e)
return result
def _generate_summary(self,
results: Dict[str, URLTestResult]) -> str:
"""生成测试摘要"""
total = len(results)
successful = sum(1 for r in results.values() if r.success)
summary = f"Network Test Summary:\n"
summary += f"Total: {total}, Successful: {successful}, Failed: {total - successful}\n\n"
for url, result in results.items():
status = "✓" if result.success else "✗"
summary += f"{status} {url}: "
if result.success:
summary += f"OK ({result.latency:.0f}ms)\n"
else:
summary += f"FAILED ({result.error})\n"
return summary

标记本节教程为已读

记录您的学习进度,方便后续查看。